package chen.web.test;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import junit.framework.TestCase;

import chen.web.user.Account;
import chen.web.user.AccountManager;
import chen.web.user.EmailAlreadyBeenRegisteredException;
import chen.web.user.InternalAccountProvider;
import chen.web.user.InternalRoleProvider;
import chen.web.user.NicknameAlreadyBeenRegisteredException;
import chen.web.user.Role;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"/test.xml"})
public class AccountManagerTesting extends TestCase{

	@Autowired
	AccountManager am;

	@Test
	public void testRegister() throws NicknameAlreadyBeenRegisteredException, EmailAlreadyBeenRegisteredException{
		Account account = am.register("helloworld", "helloworld", "helloworld@163.com");
		super.assertNotNull(account);
		Role guest = InternalRoleProvider.getGuestRole();
		super.assertTrue(account.getRole().equals(guest));
	}
	
	@Test
	public void testGetAccountByName(){
		Account acc = am.getAccountByName("helloworld");
		super.assertNotNull(acc);
	}
	
	@Test
	public void testGetAccountByEmail(){
		Account acc = am.getAccountByEmail("helloworld@163.com");
		super.assertNotNull(acc);
	}
	
	@Test
	public void testGetAccountById(){
		Account acc = am.getAccountByName("helloworld");
		Account test = am.getAccount(acc.getId());
		super.assertNotNull(test);
		super.assertEquals(acc, test);
	}
	
	@Test
	public void testGetAccountByIds(){
		Account acc = am.getAccountByName("helloworld");
		List<Integer> list = Arrays.asList(acc.getId(),acc.getId());
		List<Account> test = am.getAccount(list);
		super.assertNotNull(test);
		super.assertTrue(test.size() == 2);
	}
	
	@Test
	public void testChangeEmail() throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, InstantiationException, EmailAlreadyBeenRegisteredException{
		Account acc = am.getAccountByName("helloworld");
		am.changeEmail(acc, "change@163.com");
		super.assertEquals(acc.getEmail(), "change@163.com");
		Account test = am.getAccountByEmail("change@163.com");
		super.assertNotNull(test);
		super.assertEquals(acc, test);
		super.assertEquals(acc.getEmail(), test.getEmail());
	}
	
	@Test
	public void testChangePassword() throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, NoSuchFieldException, InstantiationException{
		Account acc = am.getAccountByName("helloworld");
		am.changePassword(acc, "hellochina");
		super.assertTrue(acc.getPassword().check("hellochina"));
		Account test = am.getAccountByName("helloworld");
		super.assertNotNull(test);
		super.assertEquals(acc, test);
		super.assertTrue(test.getPassword().check("hellochina"));
	}
	
	@Test
	public void testChangeRole(){
		Account acc = am.getAccountByName("helloworld");
		Role oldRole = acc.getRole();
		Role admin = InternalRoleProvider.getAdminRole();
		super.assertFalse(oldRole.equals(admin));
		am.changeRole(acc, InternalRoleProvider.getAdminRole());
		super.assertEquals(acc.getRole(), admin);
		Account test = am.getAccountByName("helloworld");
		super.assertEquals(test.getRole(), admin);
	}
	
	@Test
	public void testModifyAccount(){
		Account acc = am.getAccountByName("helloworld");
		acc.getExtInfo().setIntro("abc");
		am.update(acc);
		acc = am.getAccountByName("helloworld");
		super.assertNotNull(acc);
		super.assertEquals(acc.getExtInfo().getIntro(), "abc");
	}
	

	@Test
	public void testDeleteAccount(){
		Account acc = am.getAccountByName("helloworld");
		am.deleteAccount(acc);
		acc = am.getAccountByName("helloworld");
		super.assertNull(acc);
	}
	
	@Before 
	public void setUp() throws Exception {
		// TODO Auto-generated method stub
		SetCurrentAccount.set(InternalAccountProvider.getSystemAccount());
	}

}
